CVE-2017-10661 原理,触发分析
前言
最近分析了 CVE-2017-10661 这个漏洞,不过没有找到什么可以利用的点。把分析过程拿出来分享下。首先看看官方的修补代码:
上面是官方的修补代码, 可以很直观的看到,修补代码主要做了几件事:
首先在结构体里面添加了一个锁的成员变量,
然后在代码中上了锁
从这两个结论,首先就可以基本推论出来,这个漏洞应该是多线程并行,导致出来的问题。
接着继续分析修补代码,我们发现上锁的代码主要在 一下代码:
这样看不太方便,感觉有点混乱,我把这个函数从源码中找出来了
结合两段代码,我们可以看到:主要是给中间的这一段代码上了锁。那么主要问题就是出现在这一段代码当中了。
这两条分支:上面是链表添加结点;下面是移除。
两条路线分支主要是 ctx->might_cancel 这个成员变量判断的。
然后我们发现:这个变量,他是会在分支的运行过程里面修改的,蓝色的标记代码就是修改的地点。
那么我们根据上面得到的信息,可以得到一个假设:
如果两条线程同时运行这一段代码
❶ 线程1 删除了结点 并且 ctx->might_cancel = false; 那么他下次再运行的到这里的时候:
这个条件就不会成立,那么就不会运行 timerfd_remove_cancel 函数。
以上是正常情况,现在我们假设一中特殊情况
线程1 第二次执行到 else if (ctx->might_cancel) 这里的时候,CPU进行切换,切换到线程2执行。
❷ 线程2 走上面分支
设置了 ctx->might_cancel = true; 然后CPU继续执行线程1
现在 ctx->might_cancel 被线程2修改成了 true 又会执行 timerfd_remove_cancel
那么现在 timerfd_remove_cancel(ctx); 删除了两次结点 这就是漏洞的产生原理。
利用
如果猜测是对的,那么我们创建两条线程, 一条循环执行删除操作,一个执行添加操作,就会触发到漏洞。
测试过后,成功触发了漏洞。
注:看了下代码本身流程,这里删除结点,只是想节点的上下两个点的指向修改了下。
崩溃的主要原因是因为,entry->prev = LIST_POISON2; 这里执行到第二次的时候,尝试在 LIST_POISON2 写入内容,导致了崩溃。
测试机器
nexus5 5.0 hammerhead-lrx21o-factory-56a09d43 版本
附带代码: NDK-12-windows 编译
本文由看雪论坛 小白君 原创
转载请注明来自看雪社区
热门阅读
点击阅读原文/read,
更多干货等着你~